\chapter{Neo4j}
%\chapterWithAuthor{Neo4j}{Maciej Szawłowski}
\label{chap:neo4j}


Neo4j jest jedną z najpopularniejszych grafowych baz danych. Stworzona przez firmę Neo Technology ze Szwecji jest jedynym tak zaawansowanym projektem Open Source o~tej tematyce. Rozwiązanie zalicza się do metod NOSQL czyli różni się od relacyjnych baz danych (RBD) w kilku aspektach:
\begin{itemize}
\item nie używa SQL jako języka wykonywania zapytań,
\item nie wymagają ustalonego schematu danych (dane mogą być bardzo zróżnicowane),
\item mogą nie wspierać całkowicie zasad ACID\footnote{A -- {\it atomicity} -- atomowość, C -- {\it consistency} -- spójność, I -- {\it isolation} -- izolacja, D -- {\it durability} -- trwałość},
\item dobrze skaluje się horyzontalnie\footnote{Skalowanie horyzontalne oznacza łatwe zwiększanie możliwości poprzez dodawanie do infrastruktury kolejnych maszyn}.
\end{itemize}

Neo4j została zaimplementowana w Javie, co czyni ten język naturalnym kandydatem do implementacji całej aplikacji. Poniżej przedstawione zostaną możliwości współpracy z~innymi językami programowania.


\section{Wymagania i wdrożenie}
\label{sec:neo4jwdrozenie}

Bazy Neo4j można użyć na dwa sposoby -- jako nieodłączna część aplikacji\footnote{ang. embedded} korzystająca z~bibliotek umożliwiających manipulację na danych, lub jako oddzielny proces komunikujący się przez protokół HTTP. Twórcy zapewniają, że biblioteki bazy wbudowanej w aplikację zajmuje ok. 750kB. Biblioteki te istnieją tylko dla języków Java i~Python -- inne języki muszą zadowolić się samodzielną bazą oraz  REST API i związanymi z nim językami przechodzenia grafu np. Gremlin czy Cypher.

Wymagania Neo4j przedstawiono w~tablicy~\ref{table:wymaganiaNeo4j}.


\begin{table}[htb]
\begin{tabular}{l||c|c}
& Minimum & Rekomendowane\\ \hline
CPU & Intel 486 & Intel Core i7\\
Pamięć RAM & 1GB & 4-8GB\\
Dysk & SCSI, EIDE & SSD + SATA\\
System plików & ext3 & ext4, ZFS\\ \hline
Oprogramowanie & \multicolumn{2}{|c}{Java 1.6+, Linux, Windows XP, Mac OS X}
\end{tabular}
\caption{Przykładowe wymagania Neo4j podane na stronie producenta.}
\label{table:wymaganiaNeo4j}
\end{table}

\section{Metody operowania na bazie}
Neo4j jest bazą typu NOSQL czyli nie udostępnia metod języka SQL do pobierania, edycji, tworzenia czy usuwania\footnote{tzw. operacje CRUD -- {\it create}, {\it read}, {\it update}, {\it delete}}. Użytkownik (czy też programista, administrator) ma do dyspozycji kilka różnych narzędzi do operacji na zgromadzonych danych.



\subsection{Traversal API}
Neo4j udostępnia natywne API zawierające klasy oraz metody umożliwiające programistyczne poruszanie się po grafie~\cite{NeoTraverseAPI}. Za jego pomocą można zdefiniować metodę szukania, np.~w~głąb lub wszerz. Oprócz tego można wyspecyfikować warunek stopu, np.~poprzez zdefiniowane wcześniej enumaracje lub podać funkcję która oceni czy warunek został już spełniony. W podobny sposób można opisać warunki dotyczące poszukiwanej struktury, czy też jakie węzły ze znalezionej puli zwrócić.


\subsection{REST}
REST\footnote{ang. Representational State Transfer} jest bazą dla wszelkich integracji z innymi językami. Udostępnia on pewien wzorzec adresów URL oraz ich argumentów które pozwalają na poruszanie się po przestrzeni węzłów i zależności. Warto zwrócić uwagę na pewną interesującą właściwość tego API. Operacje CRUD są trywialne: polegają na wysłaniu żądania HTTP POST pod odpowiedni adres. Ciekawiej (z punktu widzenia potencjalnego napastnika) rozwiązany jest problem przechodzenia grafu. Twórcy ostrzegają, że używanie tego API wymaga dodatkowego zabezpieczenia serwera przed niepowołanym dostępem, ponieważ zapytania wywołują dynamicznie tworzony kod Groovy~\cite{NeoRestTraverse}. Nie zmienia to faktu, że dostęp poprzez HTTP czyni z~Neo4j bardzo uniwersalne rozwiązanie - język aplikacji działającej na bazie jest w tym wypadku właściwie dowolny.

\subsection{Cypher} 
Cypher~\cite{NeoCypher} jest językiem stworzonym przez Neo Technologies jako zastępstwo  SQL w ich bazie danych. W przeciwieństwie do Traversal API czy Gremlina jest językiem deklaratywnym czyli skupia się na opisie problemu, a nie na sposobie jego rozwiązania. Twórcy starali się stworzyć język który będzie maksymalnie czytelny, to znaczy, żeby stworzony kod nie wymagał dodatkowych komentarzy dotyczących swojego działania. Wyrażenie może składać się z czterech części: START, MATCH, WHERE, RETURN inspirowanych strukturą języka SQL. \\


{\bf START} opisuje węzeł z którego będziemy startować podczas szukania.

{\bf MATCH} przedstawia wzorzec wg. którego szukane będą pasujące węzły.

{\bf WHERE} jest warunkiem który musi być spełniony, aby wyszukane wzorce mogły stać się częścią wyniku.

{\bf RETURN} opisuje które węzły z zakwalifikowanych struktur powinny zostać zwrócone w~wyniku.\\

Warto zauważyć, że Cypher został stworzony niedawno, więc możliwe jest, że w najbliższym czasie nastąpią zmiany w składni. Z tego powodu istnieje również polecenie CYPHER które wskazuje którą wersję parsera języka należy użyć. Oprócz tego, język został stworzony do przeszukiwania grafu, nie udostępnia on metod do dodawania, modyfikacji ani usuwania węzłów ani krawędzi. Wspomniana wcześniej deklaratywność rozwiązuje problem dotyczący bezpieczeństwa podczas przechodzenia grafu, dlatego jest to polecana przez twórców metoda.

\subsection{Gremlin}
Gremlin~\cite{NeoGremlinPlugin} jest językiem przechodzenia grafu\footnote{ang. Graph Traversal Language} opartym na Groovy. Pozwala na tworzenie skryptów opisujących metodę wg. której należy przejść strukturę aby uzyskać wynik. Możliwości Gremlina można uzyskać używając wtyczki Neo4j Gremlin. Typowe użycie polega na przesłaniu pod odpowiedni adres żądania HTTP POST z parametrem script oraz skryptem w formie zakodowanej procentowo\footnote{ang. percent encoded -- metoda kodowania znaków specjalnych w parametrach żądań HTTP. Więcej na http://en.wikipedia.org/wiki/Percent-encoding} lub jako JSON\footnote{ang. Javascript Object Notation}. 


\section{Wsparcie dla języków oraz szkieletów aplikacji\footnote{ang. framework}}
Neo4j udostępnia REST API. Z tego powodu wybór języka czy frameworku jest właściwie dowolny. Wyżej (sekcja~\ref{sec:neo4jwdrozenie}) opisane zostały dwa podejścia wykorzystania bazy w aplikacji. Z tego powodu wymienione zostanie wsparcie poprzez biblioteki, wtyczki umożliwiające na użycie wbudowanej bazy danych.


\subsubsection{Java}
Jednym z najpopularniejszych szkieletów aplikacji w~Javie jest Spring. Zapewnia on programiście łatwy dostęp do szeregu funkcjonalności takich jak: wsparcie aplikacji internetowych, dostęp do różnorodnych baz danych, moduły zarządzania prawami dostępu czy kompatybilność z rozwiązaniami chmurowymi. Istnieje projekt open-source Spring Data mający na celu integrację technologii bazodanowych. Niedawno dodane zostały również rozwiązania typu NOSQL jak MongoDB czy Blob\footnote{Przykładem może być Simple Storage Services (S3) Amazona.} oraz Neo4j. Rozwiązanie stworzone dzięki współpracy twórców Neo4j oraz Spring pozwala na wykorzystanie wszystkich możliwości bazy.

Oczywiści istnieje wiele innych frameworków napisanych w Javie, więc użycie Neo4j (chociaż  pewnie nie tak wygodne jak w Springu) powinno być możliwe. 

\subsubsection{Python}
Zastosowanie Pythona jako głównego języka aplikacji sprowadza się do użycia JPype. Jest to projekt mający na celu stworzenie dostępu aplikacjom Pythona do bibliotek klas napisanych w Javie. Aby ułatwić cały proces, stworzone zostało specjalne API przeznaczone do tego celu. Można je zobaczyć pod adresem: \url{http://docs.neo4j.org/chunked/milestone/python-embedded.html}.

\subsubsection{Ruby}
Użycie Ruby w projektach z wbudowaną bazą Neo4j polega na wykorzystaniu wersji języka używającej wirtualną maszynę Javy - JRuby. Dzięki temu -- podobnie jak w~Pythone -- uzyskujemy dostęp do wszystkich klas Javy. 


\subsubsection{Groovy}
Groovy jest językiem rozszerzającym w pewnym stopniu i w całości kompatybilnym z Javą. Z tego powodu, wykorzystanie Neo4j w obydwu technologiach jest identyczne. Warto zwrócić uwagę na framework Grails, który posiada wtyczkę ułatwiającą pracę z bazą. Oprócz tego oparty jest na Springu, więc jakość rozwiązania jest stale podwyższana.

\section{Licencjonowanie i ceny}
Licencjonowanie, funkcjonalności oraz ceny przedstawione są w~tablicy~\ref{table:licencjeNeo4j}.

%\begin{adjustwidth}{-2cm}{-2cm
    \begin{table}[htbp]
		\begin{tabular}{p{6cm}||p{2.5cm}|p{2.5cm}|p{2.5cm}}
			{\bf Neo4j} & {\bf Community} & {\bf Advanced} & {\bf Enterprise} \\ \hline
			\hline
			{\bf Licensing} \\ \hline
			License & Open source (GPLv3)           & Commercial and AGPL & Commercial and AGPL\\
			Can be used with closed source software & Yes, except OEM & Yes, with commercial license & Yes, with commercial license\\ \hline 
			{\bf Functionality} \\ \hline
			Neo4j high performance graph database   & Yes   & Yes  & Yes\\
			Batch inserter for bulk uploads         & Yes   & Yes  & Yes\\
			Shell for console access                & Yes   & Yes  & Yes\\
			Graph algorithm package                 & Yes   & Yes  & Yes\\
			Native language bindings (Ruby, Python, Scala, Clojure, Groovy) & Yes & Yes & Yes\\
			Web frameworks integration (Spring Framework, Grails, Rails, Django, PHP and more)& Yes & Yes & Yes\\
			Neo4j Server                            & Yes   & Yes  & Yes\\  \hline
			{\bf Operations and Monitoring} \\ \hline 
			SNMP \& JMX monitoring                  &       & Yes  & Yes\\
			Neo4j Web Management console            & Basic & Full &Enterprise\\  \hline
			{\bf High load \& high availability} \\ \hline
			Online backup of running instance       &       &      & Yes \\
			Online failover to warm spare           &       &      & Yes \\
			Read slave replication                  &       &      & Yes \\
			Read/write slave replication            &       &      & Yes \\
			High availability with master failover  &       &      & Yes \\ \hline
			{\bf Support \& Services} \\ \hline
			Support hours                           &       & 5x10 & 7x24\\
			Response time                           &       & 24h  & 1h\\
			Communication channel& &Email&Phone\\
			Technical alerts                        &       & Yes  & Yes\\
			Quarterly service packs                 &       & Yes  & Yes\\
			Annual Subscription                     & Free  & USD 6000 or EUR 6000 & USD 24,000 or EUR 24,000\\
		\end{tabular}
        \caption{Licencje, funkcje oraz ceny Neo4j. Źródło: \url{http://neotechnology.com/products/price-list/}.}
        \label{table:licencjeNeo4j}
	\end{table}
%\end{adjustwidth}

\section{Dodatkowe funkcjonalności}
Wersja Enterprise posiada kilka dodatkowych funkcjonalności, które zostały przedstawione poniżej.

\subsection{High Availability}
Opcja High Availability~\cite{NeoHA} jest trybem pracy rozproszonej. Funkcjonalność ta przynosi dwie główne korzyści:

\begin{itemize}
\item zapewnia replikację danych, dzięki czemu odporność bazy na awarię sprzętu wzrasta,
\item zwiększa możliwości skalowalności - więcej instancji bazy pozwala na większą ilość odczytów w tym samym momencie.
\end{itemize} 

Neo4j HA działa w układzie master-slave. Na początku pracy przy pomocy serwisu \mbox{ZooKeeper} wybierany jest master. Podczas każdej operacji zapisu, blokowany jest master oraz instancja bazy na której wykonano operację. Zmiany stanu nie są propagowane od razu, dlatego efekt zapisu może być widoczny na innych maszynach dopiero po jakimś czasie. W przypadku gdyby master miał awarię, \mbox{ZooKeeper} przeprowadzi wybór kolejnego. Odświeżanie danych na węzłach podrzędnych zachodzi cyklicznie co określony czas. Można jednak skonfigurować węzły tak, aby synchronizacja następowała tylko podczas zapisu na tym węźle\footnote{Co dzieje się zawsze, ponieważ jest wymuszone protokołem komunikacyjnym.}. 


\subsection{Backup}
Podobnie jak w przypadku High Availability funkcja kopii zapasowej~\cite{NeoBackups} jest dostępna jedynie w najwyższej wersji Neo4j. Istnieją dwa rodzaje kopii:
\begin{enumerate}
	\item {\bf Pełna} -- pełna kopia polega na sklonowaniu całej bazy w trakcie jej działania. Nie są wykorzystywane żadne blokady - w trakcie procesu baza jest w pełni funkcjonalna. Oznacza to, że jej stan może zmienić się podczas tworzenia kopii. Dlatego zaraz po zakończeniu procesu, odtwarzane zostają z dziennika wszystkie operacje które zostały przeoczone w trakcie klonowania.
	\item{\bf Przyrostowa} -- kopia przyrostowa polega na odtworzeniu wszystkich operacji, które nastąpiły między dwoma punktami w czasie. Dzięki temu proces ten trwa dużo krócej niż tworzenie pełnej kopii. Należy pamiętać, że aby zrobić kopię przyrostową, wymagany jest pełny obraz bazy.
\end{enumerate}

Przywracanie bazy danych jest trywialnie proste: wystarczy zastąpić folder z bazą, folderem powstałym w procesie tworzenia kopii.

